home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part1 / 357 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  2.6 KB

  1. Path: jabba.ess.harris.com!usenet
  2. From: "Timothy R. Culp" <tculp@harris.com>
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Reading derived-class objects in from a file -- possible?
  5. Date: 4 Jan 1996 02:25:36 GMT
  6. Organization: Harris ISD
  7. Message-ID: <4cfdr0$ocv@jabba.ess.harris.com>
  8. References: <4ceho4$re6@lace.colorado.edu>
  9. NNTP-Posting-Host: xtwa3.ess.harris.com
  10.  
  11. Robert Dodier <dodier@colorado.edu> wrote:
  12. >
  13. > Hello,
  14. > I have a simple question but I can't seem to find a simple answer. :)
  15. > I have an abstract class, let's call it class A, and two derived classes
  16. > B and C. I would *like* to do something like this (never mind that, as
  17. > stated below, it can't work).
  18. >     A* p_something = new A;
  19. >     cin >> *p_something;
  20. >     p_something->do_whatever();
  21. > Within the program, I don't really care if someone gives a B or a C as
  22. > input -- I'll use the virtual functions of A for access anyway.
  23. > I don't want to have to write:
  24. >     cin >> ident;
  25. >     switch ( ident ) {
  26. >     case 'B': p_something = new B; break;
  27. >     case 'C': p_something = new C; break;
  28. >     }
  29.  
  30. You've touched on a classic problem that plagues everyone and
  31. unfortunately the elegant answer isn't simple.
  32.  
  33. The simplest way to approach the problem is to bury the details 
  34. of how your abstract class gets created into another class.  There
  35. is a book on the market now called "Design Patterns" that shows 
  36. an implementation of an "abstract factory" or an "object factory"
  37. that deals with the problem.  Just create another class called an
  38. A_Maker that polymorphically constructs an A from some input:
  39.  
  40.    A* p_something = A_Maker::newA(some identifier);
  41.  
  42. Your A_Maker::newA() method can be as simple as your switch
  43. statement up above.  The only problem with that is every time
  44. a new derived class is created from A, you have to remember to
  45. modify your A_Maker::newA() method.
  46.  
  47. A more elegant approach involves having your A_Maker class contain
  48. a linked list of A pointers.  Each derived class automatically
  49. links themselves into the A_Maker list.  Each derived class is
  50. also responsible for providing a method that returns true when
  51. passed an identifier.  Your A_Maker::newA() method will then loop
  52. through the list, asking each pointer if it matches the identifier
  53. passed in.  If so, it returns an instance of that pointer.
  54.  
  55.    A_Maker::newCell(const string& ident)
  56.    {
  57.       A* a = list->head();  // linked list of A ptrs;  
  58.       A* found = 0;
  59.  
  60.       while (a && !found)
  61.       {
  62.          if (a->isMyIdent(ident)) 
  63.          {
  64.             found = a->instanceOfMe();
  65.          }
  66.          else a = list->next();
  67.       }
  68.        
  69.       return found;
  70.    } 
  71.  
  72. Timothy Culp
  73. Lead Software Engineer
  74. Harris Information Systems
  75. tculp@harris.com
  76.